home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 20 / Cream of the Crop 20 (Terry Blount) (1996).iso / image / acl30bsx.zip / ACL.CPP next >
C/C++ Source or Header  |  1996-06-25  |  18KB  |  640 lines

  1. /*
  2.  * Copyright (c) 1995, 1996 Branislav L. Slantchev
  3.  * A Product of Silicon Creations, Inc.
  4.  *
  5.  * This source is distributed under the terms and conditions of the
  6.  * GNU General Library License. A copy of the license is included with
  7.  * this distrbiution (see the file 'Copying.Pbl').
  8.  *
  9.  * Contact: 73023.262@compuserve.com
  10. */
  11. #include <string.h>
  12. #include <ctype.h>
  13. #include <stdlib.h>
  14. #include <stdio.h>
  15. #include <conio.h>
  16. #include "sys/_defs.h"
  17. #include "sys/portable.h"
  18. #include "fail.h"
  19. #include "getopt.h"
  20. #include "filesys.h"
  21.  
  22. #define __VERSION__ "v3.0b"
  23.  
  24. typedef struct{
  25.     ushort size;     // data size in data file
  26.     short  lines;    // # lines in the animation
  27.     ushort delay;    // delay factor b/n steps, 0=static
  28.     short  column;   // start at column#
  29.     long   offset;   // offset of data into the data file
  30.     char   extra[4]; // spare bytes
  31. } ACL_INDEX;
  32.  
  33. // The header for the data files (.KDT)
  34. typedef struct{
  35.     char  name[80];     // name of the file, ASCIIZ
  36.     char  idString[10]; // 10 bytes id string (not ASCIIZ)
  37.     short numRecs;      // number of records stored
  38.     char  __rsrvd[58];  // reserved space
  39. } KAF_HEADER;
  40.  
  41. // The local header in the data file (.KDT)
  42. typedef struct{
  43.     char   name[26];   // name of the sequence
  44.     ushort dataSize;   // length of the record (excluding the header)
  45.     short  numLines;   // number of lines to animate
  46.     ushort speed;      // default animation speed (0 == static)
  47.     short  maxChars;   // maximum line length (0 == ignore)
  48.     char   __rsrvd[6];
  49. } KAF_RECORD;
  50.  
  51. enum Cmds {cmAdd, cmDelete, cmExport, cmShow, cmList, cmEdit, cmMerge, cmCopy};
  52. void print_help();
  53. void print_banner();
  54. void add(char*, char*, Boolean, Boolean, int, int);
  55. void list(char*);
  56. void export(char*, int);
  57. void erase(char*, int);
  58. void show(char*, int, int, int, int);
  59. void edit(char*, int, int, int, Boolean);
  60. void merge(char*, char*);
  61. void copy(char*, char*);
  62.  
  63. int
  64. main(int argc, char *argv[])
  65. {
  66.     Cmds    Command;
  67.     int     opt, nPrompt = -1, nDelay = 80, nColumn = 1, nLine = 24;
  68.     Boolean bAsk = False, bCompat = False;
  69.     char    dataPath[80], *fileSpec = 0;
  70.  
  71.     strcpy(dataPath, "a.adt");
  72.  
  73.     print_banner();
  74.  
  75.     if( 1 == argc || argv[1][0] == '?' || argv[1][1] == '?' ){
  76.         print_help();
  77.         return 1;
  78.     }
  79.  
  80.     switch( tolower(argv[1][0]) ){
  81.         case 'a': Command = cmAdd;    break;
  82.         case 'd': Command = cmDelete; break;
  83.         case 'x': Command = cmExport; break;
  84.         case 's': Command = cmShow;   break;
  85.         case 'l': Command = cmList;   break;
  86.         case 'e': Command = cmEdit;   break;
  87.         case 'm': Command = cmMerge;  break;
  88.         case 'k': Command = cmCopy;   break;
  89.         default : fail("Unknown mode: %c\n", argv[1][0]);
  90.     }
  91.  
  92.     while( EOF != (opt = getopt(argc - 1, &argv[1], "io:#:rp:c:f:y:")) ){
  93.         switch( tolower(opt) ){
  94.             case 'i': bAsk = True; break;
  95.             case 'o': file_chext(dataPath, optarg, ".adt"); break;
  96.             case '#': nPrompt = atoi(optarg); break;
  97.             case 'r': bCompat = True; break;
  98.             case 'p': nDelay = atoi(optarg); break;
  99.             case 'c': nColumn = atoi(optarg); break;
  100.             case 'f': fileSpec = optarg; break;
  101.             case 'y': nLine = atoi(optarg); break;
  102.         }
  103.     }
  104.  
  105.     switch( Command ){
  106.         case cmAdd:
  107.             add(dataPath, fileSpec, bAsk, bCompat, nDelay, nColumn);
  108.         break;
  109.         case cmList  : list(dataPath); break;
  110.         case cmExport: export(dataPath, nPrompt); break;
  111.         case cmDelete: erase(dataPath, nPrompt); break;
  112.         case cmShow  : show(dataPath, nPrompt, nDelay, nColumn, nLine); break;
  113.         case cmEdit  : edit(dataPath, nPrompt, nDelay, nColumn, bAsk); break;
  114.         case cmMerge : merge(dataPath, fileSpec); break;
  115.         case cmCopy  : copy(dataPath, fileSpec); break;
  116.     }
  117.  
  118.     return 0;
  119. }
  120.  
  121. void
  122. print_help()
  123. {
  124.     puts("Usage   : ACL <command> -<switch> [-<switch>...] -f<filespec>");
  125.     puts("Examples: ACL a -f *.ans -r, ACL l -o archive, ACL -x -#12\n");
  126.     puts("<Commands>");
  127.     puts("   a: Add files to archive          d: Delete records from archive");
  128.     puts("   l: List records in archive       s: Show animated record");
  129.     puts("   x: Export records to file        e: Edit record parameters");
  130.     puts("   m: Merge two data files          k: Copy records from a KAF file");
  131.     puts("<Switches>");
  132.     puts("   f: Specify files to add          i: Interactive mode");
  133.     puts("   r: Add RemoteAccess animations   p: Specify millisecond delay");
  134.     puts("   c: Specify starting column       #: Specify record number");
  135.     puts("   o: Use different archive name    y: Specify row for display");
  136.     puts("\nWhen adding, merging or copying, the '-f fileSpec' switch is required.");
  137.     puts("The default archive is named 'a.*', use '-o altname' to change.");
  138.     puts("Use '-i' when adding or editing to specify column and delay.");
  139. }
  140.  
  141. void
  142. print_banner()
  143. {
  144.     printf("ACL %s Copyright (c) 1995-1996 Branislav L. Slantchev. %s\n"
  145.            "A product of Silicon Creations, Inc. (part of the PB-GNU Project)"
  146.            "\n\n", __VERSION__, __DATE__);
  147. }
  148.  
  149. void
  150. add(char *data, char *spec, Boolean ask, Boolean compat, int nDelay, int column)
  151. {
  152.     char        index[80], buf[1024], base[80], path[80];
  153.     ACL_INDEX   rec;
  154.     ushort      dataLen;
  155.     FILE       *in, *dat, *idx;
  156.     int         done, total = 0;
  157.     zDosFile    ffblk;
  158.  
  159.     if( !spec ) fail("No '-f filespec' specified with 'add' command\n");
  160.  
  161.     file_chext(index, data, ".aix");
  162.     strcpy(base, file_dirspec(spec));
  163.     dat = fopen(data, "a+b");
  164.     if( !dat ) fail("unable to open data file '%s'\n", data);
  165.     idx = fopen(index, "a+b");
  166.     if( !idx ) fail("unable to open the index file '%s'\n", index);
  167.  
  168.     fseek(dat, 0L, SEEK_END);
  169.     fseek(idx, 0L, SEEK_END);
  170.     rec.column = column;
  171.     rec.delay = nDelay;
  172.     memset(rec.extra, 0, sizeof(rec.extra));
  173.     done = FindFirst(spec, 0, &ffblk);
  174.     while( !done ){
  175.         strcat(strcpy(path, base), ffblk.name);
  176.         printf("\nadding %s...", path);
  177.         in = fopen(path, "rt");
  178.         if( in ){
  179.             rec.lines = rec.size = 0;
  180.             rec.offset = ftell(dat);
  181.  
  182.             if( compat ){
  183.                 fgets(buf, sizeof(buf), in);
  184.                 sscanf(buf, "%*d %*s %*d %d", &rec.column);
  185.             }
  186.  
  187.             fgets(buf, sizeof(buf), in);
  188.             while( !feof(in) ){
  189.                 char *p = buf + strlen(buf) - 1;
  190.  
  191.                 if( '\n' == *p ) *p = EOS;
  192.                 dataLen = strlen(buf);
  193.                 rec.lines++;
  194.                 rec.size += dataLen + sizeof(ushort);
  195.                 fwrite(&dataLen, sizeof(ushort), 1, dat);
  196.                 fwrite(buf, 1, dataLen, dat);
  197.                 fgets(buf, sizeof(buf), in);
  198.             }
  199.  
  200.             if( ask ){
  201.                 printf("\nDelay (milsecs)? "); gets(buf);
  202.                 if( strlen(buf) ) rec.delay = atoi(buf);
  203.                 printf("Starting column? "); gets(buf);
  204.                 if( strlen(buf) ) rec.column = atoi(buf);
  205.             }
  206.  
  207.             fwrite(&rec, sizeof(rec), 1, idx);
  208.  
  209.             fclose(in);
  210.             printf("done (%d lines)", rec.lines);
  211.         }
  212.         total++;
  213.         done = FindNext(&ffblk);
  214.     }
  215.  
  216.     printf("\n\nAdded %d records.\n", total);
  217.     fclose(dat);
  218.     fclose(idx);
  219.  
  220.     if( 0 == file_size(data) ) file_remove(data);
  221.     if( 0 == file_size(index)) file_remove(index);
  222. }
  223.  
  224. void
  225. list(char *data)
  226. {
  227.     char       path[80];
  228.     int        total = 0;
  229.     ACL_INDEX  rec;
  230.     FILE      *fp;
  231.  
  232.     file_chext(path, data, ".aix");
  233.     fp = fopen(path, "rb");
  234.     if( fp ){
  235.         printf(" Recno   Size   Lines   Delay   Column   Offset\n"
  236.                " -----   ----   -----   -----   ------   --------\n");
  237.         fread(&rec, sizeof(rec), 1, fp);
  238.         while( !feof(fp) ){
  239.             total++;
  240.             printf(" %4d   %5d   %5d   %5d    %5d   %08lX\n",
  241.                 total, rec.size, rec.lines, rec.delay, rec.column, rec.offset);
  242.             fread(&rec, sizeof(rec), 1, fp);
  243.         }
  244.         fclose(fp);
  245.         printf(" -----------------------------------------------\n"
  246.                " Total: %d records.\n", total);
  247.     }
  248. }
  249.  
  250. void
  251. export(char *data, int nPrompt)
  252. {
  253.     char       index[80], xpath[80], buf[1024];
  254.     ACL_INDEX  rec;
  255.     FILE      *idx, *dat, *out;
  256.     int        total, start, end, exported = 0;
  257.  
  258.     file_chext(index, data, ".aix");
  259.     total = (int)(file_size(index) / sizeof(ACL_INDEX));
  260.  
  261.     if( 0 > nPrompt || total < nPrompt )
  262.         fail("Prompt number out of range (valid: 0 thru %d)\n", total);
  263.  
  264.     idx = fopen(index, "rb");
  265.     dat = fopen(data, "rb");
  266.  
  267.     if( !idx || !dat ) fail("Unable to open the data file(s)\n");
  268.  
  269.     if( 0 == nPrompt ){
  270.         start = 0;
  271.         end = total;
  272.     }
  273.     else{
  274.         start = nPrompt - 1;
  275.         end = nPrompt;
  276.     }
  277.  
  278.